package cate.game.pvp.guildwar.data;

import cate.common.table.d.GDFight;
import cate.common.table.d.GDOperation;
import cate.common.table.pvp.guildwar.row.GuildWarRankRow;
import cate.game.pvp.guildwar.data.msg.GWSideInnerUpdate;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.drop.DropConfigHelper;
import cate.game.role.Role;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.annotation.Transient;

import java.util.*;

@NoteClass("公会战-战场数据")
public class GWBattleField {

	@Transient
	@JsonIgnore
	private GuildWar parent;

	@NoteField("胜者")
	public byte winner;

	@NoteField("我方数据")
	public GuildWarFightSide a;

	@NoteField("敌方数据")
	public GuildWarFightSide b;

	@NoteField("战场日志")
	public List<GuildWarLog> logs;

	@NoteField("宝箱奖励记录")
	public Map<Integer, BoxRec> boxRwd;

	@NoteField("挑战过的玩家的uid")
	public Set<String> fightUids;


	public void initialize(GuildWar parent) {
		this.parent = parent;
		if (a == null) {
			a = new GuildWarFightSide();
		}
		a.initialize();
		if (b == null) {
			b = new GuildWarFightSide();
		}
		b.initialize();
		if (logs == null) {
			logs = new ArrayList<>();
		}
		if (boxRwd == null) {
			boxRwd = new HashMap<>();
		}
		if (fightUids == null) {
			fightUids = new HashSet<>();
		}
	}

	@JsonIgnore
	public GuildWarFightSide getSide(byte team) {
		if (GDFight.Team.A == team) {
			return a;
		} else {
			return b;
		}
	}


	public void updateOtherSide(GWSideInnerUpdate update) {
		// 对方提供的据点 如果之前没有接受过那么保存一下
		if (update.ptMap != null && !update.ptMap.isEmpty()) {
			if (a.ptMap.isEmpty()) {
				for (GuildWarPt value : update.ptMap.values()) {
					if (value.ps != null) {
						GuildWarPt pt = a.getOrBuildPt(value.ptId);
						pt.ps = value.ps.copy();
						a.ptMap.put(pt.ptId, pt);
					}
				}
			}
		}
		// 更新战场日志
		if (update.log != null) {
			addLog(update.log);
		}
		// 更新我方据点被打的信息
		if (update.pt != null) {
			GuildWarPt pt = b.ptMap.get(update.pt.ptId);
			if (pt != null) {
				pt.updateStar(update.pt.star);
			}
		}
	}

	public synchronized void addLog(GuildWarLog log){
		this.logs.add(log);
	}

	public synchronized void addRoleUid(String roleUid) {
		this.fightUids.add(roleUid);
	}

	public synchronized EcResult<Void> getBoxRwd(Role role, int pos){
		EcResult<Void> r = new EcResult<>();
		if (!fightUids.contains(role.getUid())) {
			return r.fail("未参加本次公会战");
		}
		if (winner == GDFight.Team.NONE) {
			return r.fail("尚未分出胜负");
		}
		if (boxRwd.containsKey(pos)) {
			return r.fail("该位置的宝箱已被领取");
		}
		for (BoxRec value : boxRwd.values()) {
			if (StringUtils.equals(value.roleUid, role.getUid())) {
				return r.fail("已经领过宝箱");
			}
		}
		BoxRec rec = new BoxRec();
		rec.roleUid = role.getUid();
		rec.name = role.getBase().name;
		boxRwd.put(pos, rec);
		GuildWarRankRow rankRow = role.getGame().table.guildWar.rank.findRank(parent.point);
		if (rankRow != null) {
			int dropId = winner == GDFight.Team.A ? rankRow.winBox : rankRow.failBox;
			MixRes reward = DropConfigHelper.getDropReward(role.getGame(), dropId);
			rec.reward = reward.copy();
			new MixResAdder().setRes(reward).setOperation(GDOperation.GUILD_WAR_BOX).setDialogReward(true).exe(role);
		}
		return r.success();
	}


	@JsonIgnore
	public boolean isWin() {
		int totalA = a.totalStar();
		int totalB = b.totalStar();
		if (totalA != totalB) {
			return totalA > totalB;
		} else {
			return a.profile.totalPower >= b.profile.totalPower;
		}
	}

	public void clear() {
		winner = GDFight.Team.NONE;
		a.clear();
		b.clear();
		logs.clear();
		boxRwd.clear();
		fightUids.clear();
	}

	@NoteClass("奖励记录")
	public static class BoxRec{
		@NoteField("玩家uid")
		public String roleUid;
		@NoteField("名字")
		public String name;
		@NoteField("奖励")
		public MixRes reward;
	}
}
